package com.jsh.erp.controller;



import com.jsh.erp.model.SysLoginModel;


import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;


import com.jsh.common.api.response.QueryResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

/**
 * create by: JiangYaoFeng
 *
 * @description: 授权控制器
 * <p>
 * 代码的作用:
 * 1、首先通过如 http://localhost:9090/oauth-server/authorize?client_id=c1ebe466-1cdc-4bd3-ab69-77c3561b9dee&response_type=code&redirect_uri=http://localhost:9080/oauth-client/oauth2-login
 * 2、该控制器首先检查clientId是否正确；如果错误将返回相应的错误信息
 * 3、然后判断用户是否登录了，如果没有登录首先到登录页面登录
 * 4、登录成功后生成相应的auth code即授权码，然后重定向到客户端地址，如http://localhost:9080/oauth-client/oauth2-login?code=52b1832f5dff68122f4f00ae995da0ed；在重定向到的地址中会带上code参数（授权码），接着客户端可以根据授权码去换取access token。
 */
@Controller
@RequestMapping("/oauth")
public class AuthorizeController {
    @Autowired
    RestTemplate restTemplate;

    @Value("${clientId}")
    private String clientId;

    @Value("${authorizeUrl}")
    private String authorizeUrl;

    @Value("${redirectUrl}")
    private String redirectUrl;

    @Value("${response_type}")
    private String response_type;

    @Value("${clientSecret}")
    private String clientSecret;

    @Value("${accessTokenUrl}")
    private String accessTokenUrl;



    /**
     * create by: JiangYaoFeng
     * description: client的接口
     */


    //客户端向资源拥有者(第三方)发起获取授权请求
    @RequestMapping("/login")
    @ResponseBody
    public QueryResponseResult login(@RequestBody SysLoginModel sysLoginModel) throws OAuthProblemException {
        String url = authorizeUrl + "?response_type=" + response_type
                + "&redirect_uri=" + redirectUrl
                + "&client_id=" + clientId;


        QueryResponseResult queryResponseResult = restTemplate.postForObject(url, sysLoginModel, QueryResponseResult.class);

        return queryResponseResult;
    }

    //接受客户端返回的code，提交申请access token的请求
    @RequestMapping("/callbackCode")
    @ResponseBody
    public String toLogin(HttpServletRequest request) throws OAuthProblemException {

        String code = request.getParameter("code");

        System.out.println("==> 服务端回调，获取的code：" + code);

        OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

        try {

            OAuthClientRequest accessTokenRequest = OAuthClientRequest
                    .tokenLocation(accessTokenUrl)
                    .setGrantType(GrantType.AUTHORIZATION_CODE)
                    .setClientId(clientId)
                    .setClientSecret(clientSecret)
                    .setCode(code)
                    .setRedirectURI(redirectUrl)
                    .buildQueryMessage();


            //去服务端请求access token，并返回响应
            OAuthAccessTokenResponse oAuthResponse = oAuthClient.accessToken(accessTokenRequest, OAuth.HttpMethod.POST);
            //获取服务端返回过来的access token
            String accessToken = oAuthResponse.getAccessToken();
            //查看access token是否过期
            Long expiresIn = oAuthResponse.getExpiresIn();
            System.out.println("==> 客户端根据 code值 " + code + " 到服务端获取的access_token为：" + accessToken + " 过期时间为：" + expiresIn);


            return accessToken;
        } catch (OAuthSystemException e) {
            e.printStackTrace();
        }
        return "";
    }




}
